package com.imut.lagain.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.TimeUnit;

/**
 * 时间处理工具类
 */
public class DateTimeUtil {
    private static final Logger log = LoggerFactory.getLogger(DateTimeUtil.class);
    public static final String DEFAULT_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
    public static final String COMPACT_DATETIME_FORMAT = "yyyyMMddHHmmss";
    public static final String CHINESE_DATETIME_FORMAT = "yyyy年MM月dd日 HH:mm:ss";
    private static final DateTimeFormatter DEFAULT_DATETIME_FORMATTER = DateTimeFormatter.ofPattern(DEFAULT_DATETIME_FORMAT);
    private static final DateTimeFormatter DEFAULT_DATE_FORMATTER = DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT);
    private static final DateTimeFormatter DEFAULT_TIME_FORMATTER = DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT);
    private static final DateTimeFormatter COMPACT_DATETIME_FORMATTER = DateTimeFormatter.ofPattern(COMPACT_DATETIME_FORMAT);
    private static final DateTimeFormatter CHINESE_DATETIME_FORMATTER = DateTimeFormatter.ofPattern(CHINESE_DATETIME_FORMAT);
    
    /**
     * 格式化日期时间（默认格式）
     * @param dateTime 日期时间
     * @return 格式化字符串
     */
    public static String format(LocalDateTime dateTime) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.format(DEFAULT_DATETIME_FORMATTER);
    }
    
    /**
     * 格式化日期时间（自定义格式）
     * @param dateTime 日期时间
     * @param pattern 格式模式
     * @return 格式化字符串
     */
    public static String format(LocalDateTime dateTime, String pattern) {
        if (dateTime == null || pattern == null) {
            return null;
        }
        return dateTime.format(DateTimeFormatter.ofPattern(pattern));
    }
    
    /**
     * 格式化为日期字符串
     * @param dateTime 日期时间
     * @return 日期字符串
     */
    public static String formatDate(LocalDateTime dateTime) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.format(DEFAULT_DATE_FORMATTER);
    }
    
    /**
     * 格式化为时间字符串
     * @param dateTime 日期时间
     * @return 时间字符串
     */
    public static String formatTime(LocalDateTime dateTime) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.format(DEFAULT_TIME_FORMATTER);
    }
    
    /**
     * 格式化为紧凑格式
     * @param dateTime 日期时间
     * @return 紧凑格式字符串
     */
    public static String formatCompact(LocalDateTime dateTime) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.format(COMPACT_DATETIME_FORMATTER);
    }
    
    /**
     * 格式化为中文格式
     * @param dateTime 日期时间
     * @return 中文格式字符串
     */
    public static String formatChinese(LocalDateTime dateTime) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.format(CHINESE_DATETIME_FORMATTER);
    }
    
    /**
     * 解析日期时间字符串（默认格式）
     * @param dateTimeStr 日期时间字符串
     * @return LocalDateTime对象
     */
    public static LocalDateTime parse(String dateTimeStr) {
        if (dateTimeStr == null || dateTimeStr.trim().isEmpty()) {
            return null;
        }
        return LocalDateTime.parse(dateTimeStr, DEFAULT_DATETIME_FORMATTER);
    }
    
    /**
     * 解析日期时间字符串（自定义格式）
     * @param dateTimeStr 日期时间字符串
     * @param pattern 格式模式
     * @return LocalDateTime对象
     */
    public static LocalDateTime parse(String dateTimeStr, String pattern) {
        if (dateTimeStr == null || dateTimeStr.trim().isEmpty() || pattern == null) {
            return null;
        }
        return LocalDateTime.parse(dateTimeStr, DateTimeFormatter.ofPattern(pattern));
    }
    
    /**
     * 获取当前时间
     * @return 当前时间
     */
    public static LocalDateTime now() {
        return LocalDateTime.now();
    }
    
    /**
     * 获取今天开始时间（00:00:00）
     * @return 今天开始时间
     */
    public static LocalDateTime todayStart() {
        return LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0);
    }
    
    /**
     * 获取今天结束时间（23:59:59）
     * @return 今天结束时间
     */
    public static LocalDateTime todayEnd() {
        return LocalDateTime.now().withHour(23).withMinute(59).withSecond(59).withNano(999999999);
    }
    
    /**
     * 计算两个时间之间的天数差
     * @param start 开始时间
     * @param end 结束时间
     * @return 天数差
     */
    public static long daysBetween(LocalDateTime start, LocalDateTime end) {
        if (start == null || end == null) {
            return 0;
        }
        return ChronoUnit.DAYS.between(start, end);
    }
    
    /**
     * 计算两个时间之间的小时差
     * @param start 开始时间
     * @param end 结束时间
     * @return 小时差
     */
    public static long hoursBetween(LocalDateTime start, LocalDateTime end) {
        if (start == null || end == null) {
            return 0;
        }
        return ChronoUnit.HOURS.between(start, end);
    }
    
    /**
     * 计算两个时间之间的分钟差
     * @param start 开始时间
     * @param end 结束时间
     * @return 分钟差
     */
    public static long minutesBetween(LocalDateTime start, LocalDateTime end) {
        if (start == null || end == null) {
            return 0;
        }
        return ChronoUnit.MINUTES.between(start, end);
    }
    
    /**
     * 计算两个时间之间的秒数差
     * @param start 开始时间
     * @param end 结束时间
     * @return 秒数差
     */
    public static long secondsBetween(LocalDateTime start, LocalDateTime end) {
        if (start == null || end == null) {
            return 0;
        }
        return ChronoUnit.SECONDS.between(start, end);
    }
    
    /**
     * 添加天数
     * @param dateTime 原时间
     * @param days 天数
     * @return 新时间
     */
    public static LocalDateTime plusDays(LocalDateTime dateTime, long days) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.plusDays(days);
    }
    
    /**
     * 添加小时
     * @param dateTime 原时间
     * @param hours 小时数
     * @return 新时间
     */
    public static LocalDateTime plusHours(LocalDateTime dateTime, long hours) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.plusHours(hours);
    }
    
    /**
     * 添加分钟
     * @param dateTime 原时间
     * @param minutes 分钟数
     * @return 新时间
     */
    public static LocalDateTime plusMinutes(LocalDateTime dateTime, long minutes) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.plusMinutes(minutes);
    }
    
    /**
     * 减去天数
     * @param dateTime 原时间
     * @param days 天数
     * @return 新时间
     */
    public static LocalDateTime minusDays(LocalDateTime dateTime, long days) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.minusDays(days);
    }
    
    /**
     * 减去小时
     * @param dateTime 原时间
     * @param hours 小时数
     * @return 新时间
     */
    public static LocalDateTime minusHours(LocalDateTime dateTime, long hours) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.minusHours(hours);
    }
    
    /**
     * 减去分钟
     * @param dateTime 原时间
     * @param minutes 分钟数
     * @return 新时间
     */
    public static LocalDateTime minusMinutes(LocalDateTime dateTime, long minutes) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.minusMinutes(minutes);
    }
    
    /**
     * 判断是否为同一天
     * @param date1 日期1
     * @param date2 日期2
     * @return 是否为同一天
     */
    public static boolean isSameDay(LocalDateTime date1, LocalDateTime date2) {
        if (date1 == null || date2 == null) {
            return false;
        }
        return date1.toLocalDate().equals(date2.toLocalDate());
    }
    
    /**
     * 判断是否为今天
     * @param dateTime 日期时间
     * @return 是否为今天
     */
    public static boolean isToday(LocalDateTime dateTime) {
        if (dateTime == null) {
            return false;
        }
        return isSameDay(dateTime, LocalDateTime.now());
    }
    
    /**
     * 判断是否为过去时间
     * @param dateTime 日期时间
     * @return 是否为过去时间
     */
    public static boolean isPast(LocalDateTime dateTime) {
        if (dateTime == null) {
            return false;
        }
        return dateTime.isBefore(LocalDateTime.now());
    }
    
    /**
     * 判断是否为未来时间
     * @param dateTime 日期时间
     * @return 是否为未来时间
     */
    public static boolean isFuture(LocalDateTime dateTime) {
        if (dateTime == null) {
            return false;
        }
        return dateTime.isAfter(LocalDateTime.now());
    }
    
    /**
     * 获取友好的时间描述
     * @param dateTime 日期时间
     * @return 友好描述
     */
    public static String getFriendlyTime(LocalDateTime dateTime) {
        if (dateTime == null) {
            return "未知时间";
        }
        
        LocalDateTime now = LocalDateTime.now();
        long seconds = secondsBetween(dateTime, now);
        
        if (seconds < 0) {
            seconds = -seconds;
            if (seconds < 60) {
                return "即将";
            } else if (seconds < 3600) {
                return (seconds / 60) + "分钟后";
            } else if (seconds < 86400) {
                return (seconds / 3600) + "小时后";
            } else {
                return (seconds / 86400) + "天后";
            }
        } else {
            if (seconds < 60) {
                return "刚刚";
            } else if (seconds < 3600) {
                return (seconds / 60) + "分钟前";
            } else if (seconds < 86400) {
                return (seconds / 3600) + "小时前";
            } else if (seconds < 2592000) { // 30天
                return (seconds / 86400) + "天前";
            } else {
                return formatDate(dateTime);
            }
        }
    }
}
